home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #6 / Amiga Plus CD - 2004 - No. 06.iso / AmiSoft / Comm / misc / trsi-ftpd01.lha / FAME-FTPd / source / Config / main.c < prev    next >
C/C++ Source or Header  |  2004-04-24  |  38KB  |  931 lines

  1. /****************************************************************************************
  2.  *  PROJECT: FAME-FTPd
  3.  *     FILE: main.c
  4.  *  PURPOSE: FAME-FTPdCFG - Configuration tool for FAME-FTPd
  5.  *  CREATED: 03-AUG-2003
  6.  * MODIFIED: 24-APR-2004
  7.  *   AUTHOR: Sascha 'SieGeL' Pfalz
  8.  ****************************************************************************************/
  9.  
  10. #include <proto/muimaster.h>
  11. #include <mui/InfoText_mcc.h>
  12. #include <MUI/nlistview_mcc.h>
  13. #include <MUI/nlist_mcc.h>
  14. #include <proto/dos.h>
  15. #include <proto/exec.h>
  16. #include <proto/asl.h>
  17. #include <proto/fame.h>
  18. #include <proto/intuition.h>
  19. #include <libraries/fame.h>
  20. #include <fame/fame.h>
  21. #include <exec/memory.h>
  22. #include <libraries/mui.h>
  23. #include <libraries/asl.h>
  24. #include <libraries/fame.h>
  25. #include "version.h"
  26. #include "/struct.h"
  27. #include "/global_defines.h"
  28. #include "inno.h"
  29.  
  30. struct    Library *MUIMasterBase=NULL;
  31.  
  32. LONG         __stack = 16184L;                                                    // Ab MUI V3.0 ABSOLUT ZWINGEND!!!
  33.  
  34. APTR         app,mainwindow=NULL,strip,aboutwin,adv_lv,adv_txt,fnamelength,fbufsize;
  35.  
  36. APTR         howto,debugwin,usedns,uldir,timeout,            // All configuration options
  37.                 ipfile,titlefile,portlo,porthi,
  38.                 logdir,maxusers,weektop,
  39.                 savebtn,cancelbtn;
  40.  
  41. STRPTR     Pages[]={"Pathes","Options","Task Monitor",NULL};
  42.  
  43. static    char *docpathes[]={"PROGDIR:FAME-FTPd.guide","FAME:Documentation/FAME-FTPd.guide",NULL};
  44.  
  45. /**************************************************************************************************
  46.  * Prototypes
  47.  **************************************************************************************************/
  48.  
  49. void         main(void);
  50. void         __autoopenfail(void) { _XCEXIT(0);}
  51. void         fail(APTR, char *,BOOL);
  52. void         SPrintf(char *Buffer,char *ctl, ...) { RawDoFmt(ctl, (long *)(&ctl + 1), (void (*))"\x16\xc0\x4e\x75",Buffer);}
  53. void         GetUserName(long userid, char *buffer);
  54. void         GetConfName(long confid, char *buffer);
  55.  
  56. STATIC     void ShowAbout(void);                                // Displays the About Window
  57. STATIC     void RemoveAboutWin(void);                 // Removes About Window
  58. STATIC     void DoubleStart(void);                    // Avoids double starts
  59. STATIC     void SavePrefs(void);                                // Saves preferences
  60. STATIC     void LoadPrefs(void);                                // Loads preferences
  61. STATIC     void UpdateStatDisplay(void);
  62.  
  63. /* Help functions for easier creation of MUI objects */
  64.  
  65. APTR         CreatePopObject(long num,char key,char *help);
  66. APTR         CreateKeyButton(char *label, char key,char *help);
  67. APTR         CreateKeyCheckMark(BOOL status, char key, char *help);
  68. APTR         CreateInteger(char key,long weight,long maxlen,long contents,char *help);
  69.  
  70. /* Hooks for Filerequester and NewList */
  71.  
  72. SAVEDS     ASM ULONG     PrefsPopupFunc(REG(a0) struct Hook *hook, REG(a1) void *args, REG(a2) APTR obj);
  73. SAVEDS     ASM struct    FTPdStats *adv_confunc(REG(a0) struct Hook *hook,REG(a2) APTR mem_pool, REG(a1) struct FTPdStats *fs);
  74. SAVEDS     ASM long         adv_desfunc(REG(a0) struct Hook *hook,REG(a2) APTR mem_pool,REG(a1) struct FTPdStats *line);
  75. SAVEDS     ASM long         adv_dspfunc(REG(a0) struct Hook *hook,REG(a2) char **array,REG(a1) struct FTPdStats *line);
  76.  
  77. static     struct Hook adv_conhook            =    {{NULL, NULL},(void *)adv_confunc,NULL,NULL};
  78. static     struct Hook adv_deshook            =    {{NULL, NULL},(void *)adv_desfunc,NULL,NULL};
  79. static     struct Hook adv_dsphook            =    {{NULL, NULL},(void *)adv_dspfunc,NULL,NULL};
  80. static     struct Hook PrefsPopupHook     = {{NULL, NULL},(void *)PrefsPopupFunc,    NULL, NULL};
  81.  
  82. /**************************************************************************************************
  83.  * FUNCTION: main()
  84.  *  PURPOSE: Start of program
  85.  *    INPUT: none
  86.  *   RETURN: none
  87.  **************************************************************************************************/
  88.  
  89. void main(void)
  90.     {
  91.     char    buffer[256],docpath[256];
  92.     APTR    mypic,myregister;
  93.     BPTR    testit;
  94.  
  95.     if(!(IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",39L))) { exit(20); }
  96.     if(!(MUIMasterBase=OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))) fail(NULL,"Failed to open "MUIMASTER_NAME" V12++ !",TRUE);
  97.   if(!(UtilityBase=OpenLibrary("utility.library",37L))) fail(NULL,"Failed to open utility.library V37++ !",TRUE);
  98.     if(!(FAMEBase=(struct FAMELibrary *)OpenLibrary(FAMENAME,4))) fail(NULL,"Failed to open FAME.library V4++ !!!",TRUE);
  99.     if(!(mem_pool=CreatePool(MEMF_CLEAR|MEMF_PUBLIC,20480L,20480L))) fail(NULL,"Cannot allocate 20k memory pool??",TRUE);
  100.     if(!(fconfig = AllocPooled(mem_pool,sizeof(struct FTPdConfig)))) fail(NULL,"Cannot allocate prefs struct!",TRUE);
  101.     if(!(fib = AllocDosObject(DOS_FIB,NULL)))
  102.         {
  103.         fail(NULL,"Cannot allocate FIB struct!",TRUE);
  104.         }
  105.     testit = Lock(docpathes[0],ACCESS_READ);
  106.     if(testit)
  107.         {
  108.         UnLock(testit);
  109.         FAMEStrCopy(docpathes[0],docpath,255);
  110.         }
  111.     else FAMEStrCopy(docpathes[1],docpath,255);
  112.     app = ApplicationObject,
  113.         MUIA_Application_Title      , "FAME-FTPdCFG",
  114.         MUIA_Application_Version    , "$VER: FAME-FTPdCFG "COMPILE_VERSION" ("COMPILE_DATE") ["CPU_TYPE"]\0",
  115.         MUIA_Application_Copyright  , "Copyright ©2003-2004, Sascha 'SieGeL/tRSi' Pfalz",
  116.         MUIA_Application_Author     , "Sascha 'SieGeL/tRSi' Pfalz",
  117.         MUIA_Application_Description, "Configuration for FAME-FTPd",
  118.         MUIA_Application_Base       , "FAME-FTPdCFG",
  119.         MUIA_Application_SingleTask , TRUE,
  120.         MUIA_Application_HelpFile        , docpath,
  121.          MUIA_Application_Menustrip    , strip = MenustripObject,
  122.             MUIA_Family_Child                    , MenuObjectT("Project"),
  123.               MUIA_Family_Child                , MenuitemObject,
  124.                   MUIA_Menuitem_Title   , "Save",
  125.                   MUIA_Menuitem_Shortcut, "S",
  126.                     MUIA_UserData                    ,    ID_SAVE,
  127.               End,
  128.               MUIA_Family_Child                , MenuitemObject,
  129.                   MUIA_Menuitem_Title   , "Update Task Monitor",
  130.                   MUIA_Menuitem_Shortcut, "U",
  131.                     MUIA_UserData                    ,    ID_UPDATE,
  132.               End,
  133.               MUIA_Family_Child                , MenuitemObject,
  134.                     MUIA_Menuitem_Title        , NM_BARLABEL,
  135.               End,
  136.               MUIA_Family_Child                , MenuitemObject,
  137.                   MUIA_Menuitem_Title   , "About",
  138.                   MUIA_Menuitem_Shortcut, "?",
  139.                     MUIA_UserData                    ,    ID_ABOUT,
  140.               End,
  141.               MUIA_Family_Child                , MenuitemObject,
  142.                   MUIA_Menuitem_Title   , "About MUI...",
  143.                   MUIA_Menuitem_Shortcut, "!",
  144.                     MUIA_UserData                    ,    ID_ABOUT_MUI,
  145.               End,
  146.               MUIA_Family_Child                , MenuitemObject,
  147.                     MUIA_Menuitem_Title        , NM_BARLABEL,
  148.               End,
  149.               MUIA_Family_Child                , MenuitemObject,
  150.                   MUIA_Menuitem_Title   , "Quit",
  151.                   MUIA_Menuitem_Shortcut, "Q",
  152.                     MUIA_UserData                    ,    MUIV_Application_ReturnID_Quit,
  153.               End,
  154.         End,
  155.         End,
  156.         SubWindow, mainwindow = WindowObject,
  157.             MUIA_Window_ID         , MAKE_ID('M','A','I','N'),
  158.             MUIA_Window_Title      , "FAME-FTPdCFG V"COMPILE_VERSION" by Sascha 'SieGeL/tRSi' Pfalz",
  159.             MUIA_Window_AppWindow  , FALSE,
  160.             MUIA_Window_ScreenTitle,"FAME-FTPdCFG V"COMPILE_VERSION" ("COMPILE_DATE") ["CPU_TYPE"]\0",
  161.             WindowContents, VGroup,
  162.                 Child, mypic=TextObject,TextFrame,MUIA_Background,MUII_SHADOWFILL,End,
  163.                 Child, myregister=RegisterGroup(Pages),
  164.                     MUIA_Register_Frame, TRUE,
  165.                     Child, VGroup,
  166.                         Child, ColGroup(2),
  167.                             Child, KeyLabel2("Login ASCII:"                            ,'a'),Child,titlefile = CreatePopObject(ID_TITLEFILE    ,'a',"CONFIG"),
  168.                             Child, KeyLabel2("Upload Description File:"    ,'h'),Child,howto         = CreatePopObject(ID_ULHELPFILE    ,'h',"CONFIG"),
  169.                             Child, KeyLabel2("Temporary Upload Path:"        ,'t'),Child,uldir         = CreatePopObject(ID_ULTEMPDIR    ,'t',"CONFIG"),
  170.                             Child, KeyLabel2("Logfile:"                                    ,'l'),Child,logdir         = CreatePopObject(ID_LOGDIR            ,'l',"CONFIG"),
  171.                             Child, KeyLabel2("Use passive IP from file:",'i'),Child,ipfile        = CreatePopObject(ID_IPFILE            ,'i',"CONFIG"),
  172.                         End,
  173.                     End,
  174.                     Child, VGroup,
  175.             Child, VGroup,
  176.                             Child, ColGroup(4),GroupFrame,
  177.                                 Child, KeyLabel1("Use Debug-Window:"    ,'d'),Child,debugwin= CreateKeyCheckMark(FALSE    ,'d',"CONFIG"),
  178.                                 Child, KeyLabel1("Resolve Hostnames:"    ,'r'),Child,usedns    = CreateKeyCheckMark(TRUE    ,'r',"CONFIG"),
  179.                                 Child, KeyLabel1("aCID-tOP sUPPORT:"    ,'a'),Child,weektop    = CreateKeyCheckMark(FALSE    ,'a',"CONFIG"),
  180.                                 Child, Label("Max. Filename length:"),    Child,fnamelength = MUI_MakeObject(MUIO_NumericButton,"Max. Filename length:",12,107,"%3ld"),
  181.                                 Child, Label("Filecopy Buffer Size:"),    Child,fbufsize        = MUI_MakeObject(MUIO_NumericButton,"Max. Filename length:",256,1024,"%4ldkb"),
  182.                                 Child, Label("Timeout in Minutes:"),        Child,timeout            = MUI_MakeObject(MUIO_NumericButton,"Timeout in Minutes:",1,15,"%ldmin"),
  183.                             End,
  184.                             Child, ColGroup(4), GroupFrameT("Passive port range"),
  185.                                 Child, KeyLabel1("From:",'f'),
  186.                                 Child, portlo     = CreateInteger('f',100,5,0,"CONFIG"),
  187.                 Child, KeyLabel1("To:",'t'),
  188.                                 Child, porthi     = CreateInteger('t',100,5,0,"CONFIG"),
  189.                             End,
  190.                             Child, ColGroup(2), GroupFrame,
  191.                                 Child, KeyLabel1("Max. User allowed:",'M'),
  192.                                 Child, maxusers = CreateInteger('M',100,5,0,"CONFIG"),
  193.               End,
  194.                       End,
  195.                     End,
  196.                     Child, VGroup, GroupFrameT("Task Monitor"),
  197.                         Child, adv_txt= TextObject, TextFrame, MUIA_Background, MUII_TextBack,End,
  198.                         Child, adv_lv = NListviewObject,
  199.                   MUIA_ShortHelp,                            "Shows active connections on your FAME-FTPd Server",
  200.                             MUIA_NListview_NList,                NListObject,
  201.                         MUIA_NList_Input,                        TRUE,
  202.                             MUIA_NList_DoubleClick,            TRUE,
  203.                             MUIA_HelpNode,                            "ADV_LV",
  204.                             InputListFrame,
  205.                                 MUIA_List_ConstructHook,    &adv_conhook,
  206.                                 MUIA_List_DestructHook,        &adv_deshook,
  207.                                 MUIA_List_DisplayHook,        &adv_dsphook,
  208.                                 MUIA_List_Format,                    "P=\33l BAR,P=\33l BAR,P=\33l BAR,P=\33l BAR,P=\33l",
  209.                                 MUIA_List_Title,                    TRUE,
  210.                                 ReadListFrame,
  211.                             End,
  212.                         End,
  213.                     End,
  214.                 End,
  215.                 Child, VGroup, GroupFrame,
  216.                     Child, ColGroup(2),
  217.                          MUIA_Group_SameSize, TRUE,
  218.                         Child, savebtn    = CreateKeyButton("Save Prefs",'s',"SAVE_PREFS"),
  219.                         Child, cancelbtn= CreateKeyButton("Cancel",'c',"CANCEL_PREFS"),
  220.                     End,
  221.                 End,
  222.             End,
  223.         End,
  224.     End;
  225.     if(!app) fail(app,"Unable to create Main window!",TRUE);
  226.     LoadPrefs();
  227.      DoMethod(mainwindow    ,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,    app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  228.   DoMethod(cancelbtn     ,MUIM_Notify,MUIA_Pressed,FALSE,               app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  229.     DoMethod(savebtn       ,MUIM_Notify,MUIA_Pressed,FALSE,                 app,2,MUIM_Application_ReturnID,ID_SAVE);
  230.     DoMethod(app                ,MUIM_Notify,MUIA_Application_DoubleStart, MUIV_EveryTime,app,2,MUIM_Application_ReturnID,ID_DOUBLESTART);
  231.     DoMethod(mypic            ,MUIM_SetAsString,MUIA_Text_Contents,"\33c\0338\33bFAME-FTPdCFG V%s Build %ld (%s)\33n\nwritten by Sascha 'SieGeL/tRSi' Pfalz",COMPILE_VERSION,COMPILE_BUILD,COMPILE_DATE);
  232.  
  233.     // Install Bubble Help texts:
  234.  
  235.     set(howto,                MUIA_ShortHelp,        "This file will be displayed\nin every conference as a short help.\nGive here the full path to your textfile.\nDefaults to HOW_TO_UPLOAD.TXT");
  236.     set(uldir,                MUIA_ShortHelp,        "Enter here the path where all temporary uploads should be placed.\nA good choice is RAM: to avoid disk fragmentation.");
  237.     set(debugwin,            MUIA_ShortHelp,        "Enable this option to automatically open a console\nwindow on your WB screen for debugging purposes.");
  238.     set(usedns,                MUIA_ShortHelp,        "Enable this option to have all connected IP addresses\nresolved to their Hostnames (if possible).\nThis may take some time if the DNS is slow, so you may disable it.\nAffects all logs, too!");
  239.     set(fnamelength,    MUIA_ShortHelp,        "You can define here the maximum allowed filename\nlength that can be used for uploaded files.\nPlease do not use filenames > 31 characters,\nas most doors cannot handle this correctly!");
  240.     set(fbufsize,            MUIA_ShortHelp,        "Choose the buffer size for copying uploaded files to the FAME directories.\nYou can choose between 256kb - 1024kb.");
  241.     set(timeout,            MUIA_ShortHelp,        "Choose how many minutes the server should wait until a timeout occures.\nRecommended setting is 10 minutes.");
  242.     set(cancelbtn,        MUIA_ShortHelp,        "Cancels Preferences and exits.");
  243.     set(ipfile,                MUIA_ShortHelp,        "Enter here the full path and name to a file\ncontaining an ip address which should be used\nfor passive responses. Leave empty to use the\nip address of the interface the connection was\nestablished.\nYou can of course add also a hostname to that file\n(i.e. blub.dyndns.org) the FTP Server will try to\nresolve the hostname before using it.");
  244.     set(titlefile,        MUIA_ShortHelp,        "You may optionally enter here\nan ASCII / ANSI file which will\nbe shown to the client right\nafter connecting.");
  245.     set(portlo,                MUIA_ShortHelp,        "You may specify a port range to use for passive connections.\nA value of 0 means that the TCP stack will auto-choose the port numbers.\nIf you are however behind a firewall you may need to explictly specify what\nports can be used. Please specify in this case range between 1-32767 for \nport usage. Of course the minimum portrange must be lower than maxmimum\nand you should also make sure to have at least 5 ports free, else you may\nrun into trouble! Normal users should leave both values at default value of 0.");
  246.     set(porthi,                MUIA_ShortHelp,        "You may specify a port range to use for passive connections.\nA value of 0 means that the TCP stack will auto-choose the port numbers.\nIf you are however behind a firewall you may need to explictly specify what\nports can be used. Please specify in this case range between 1-32767 for \nport usage. Of course the minimum portrange must be lower than maxmimum\nand you should also make sure to have at least 5 ports free, else you may\nrun into trouble! Normal users should leave both values at default value of 0.");
  247.     set(weektop,            MUIA_ShortHelp,        "If you have aCID-tOP installed enable this option.\nThe FTP server will write special files after every upload\nso that the aCID-tOP tool can count also your FTP uploads.\nThis of course works only with my aCID-tOP tool.");
  248.   set(logdir,                MUIA_ShortHelp,        "Enter here a filename where the FTPServer should write the logfile.");
  249.     set(maxusers,            MUIA_ShortHelp,        "You can enter here a maximum count of simultaenous online users.\nIf this limit is reached no new connections are allowed.\nSet to 0 to disable MaxUser check");
  250.  
  251.     SPrintf(buffer,"Saves the preferences file to\n%s",prefspath);
  252.     set(savebtn,          MUIA_ShortHelp,     buffer);
  253.  
  254.     // Finally set all preferences data to our GUI objects:
  255.  
  256.   set(howto            ,    MUIA_String_Contents,fconfig->HowToUploadFile);
  257.     set(uldir            , MUIA_String_Contents,fconfig->UploadTempPath);
  258.     set(ipfile        , MUIA_String_Contents,fconfig->IPFile);
  259.     set(titlefile    , MUIA_String_Contents,fconfig->TitleFile);
  260.     set(logdir        , MUIA_String_Contents,fconfig->LogFile);
  261.  
  262.     if(fconfig->Flags1 & CFG_USEDEBUG) setcheckmark(debugwin,TRUE);
  263.     else setcheckmark(debugwin,FALSE);
  264.     if(fconfig->Flags1 & CFG_USEDNS)     setcheckmark(usedns,TRUE);
  265.     else setcheckmark(usedns,FALSE);
  266.     if(fconfig->Flags1 & CFG_WEEKTOP)    setcheckmark(weektop,TRUE);
  267.     else setcheckmark(weektop,FALSE);
  268.     set(fnamelength    ,MUIA_Numeric_Value,fconfig->FileNameLength);
  269.     set(fbufsize        ,MUIA_Numeric_Value,fconfig->FileBufferSize);
  270.     set(timeout            ,MUIA_Numeric_Value,fconfig->Timeout/60);
  271.  
  272.   SPrintf(buffer,"%ld",fconfig->PortLo);         set(portlo    ,MUIA_String_Contents,buffer);
  273.     SPrintf(buffer,"%ld",fconfig->PortHi);         set(porthi    ,MUIA_String_Contents,buffer);
  274.   SPrintf(buffer,"%ld",fconfig->MaxUsers);    set(maxusers,MUIA_String_Contents,buffer);
  275.  
  276.     // And now: open the main window :)
  277.  
  278.     set(mainwindow,MUIA_Window_Open,TRUE);
  279.     UpdateStatDisplay();
  280.     {
  281.     ULONG sigs = 0;
  282.   ULONG    retcode;
  283.  
  284.     do
  285.         {
  286.         retcode = DoMethod(app,MUIM_Application_NewInput,&sigs);
  287.         if (sigs)
  288.             {
  289.             sigs = Wait(sigs | SIGBREAKF_CTRL_C);
  290.             if (sigs & SIGBREAKF_CTRL_C) break;
  291.             }
  292.         switch(retcode)
  293.             {
  294.             case ID_SAVE:                    SavePrefs();
  295.                                                         break;
  296.  
  297.             case ID_ABOUT:                ShowAbout();
  298.                                                         break;
  299.  
  300.             case ID_ABOUTCLOSE:        RemoveAboutWin();
  301.                                                         break;
  302.  
  303.             case ID_ABOUT_MUI:        if(!aboutwin)
  304.                                     {
  305.                                                             aboutwin=AboutmuiObject,
  306.                                          MUIA_Window_RefWindow,mainwindow,
  307.                                                                 MUIA_Aboutmui_Application,app,
  308.                                    End;
  309.                                                             }
  310.                                                         if(aboutwin) set(aboutwin,MUIA_Window_Open,TRUE);
  311.                                                         else fail(app,"Unable to open MUI About window",TRUE);
  312.                                                         break;
  313.  
  314.             case ID_DOUBLESTART:  DoubleStart();
  315.                             break;
  316.  
  317.             case ID_UPDATE:                UpdateStatDisplay();
  318.                                                         break;
  319.             }
  320.         }while(retcode != MUIV_Application_ReturnID_Quit);
  321.     }
  322.      set(mainwindow,MUIA_Window_Open,FALSE);
  323.     fail(app,"",TRUE);
  324.     }
  325.  
  326. /**************************************************************************************************
  327.  * FUNCTION: PrefsPopUpFunc()
  328.  *  PURPOSE: Hook function for File-PopUp objects
  329.  *    INPUT: hook        => Pointer to hook structure PrefsPopupHook
  330.  *           args        => Arguments passed (not used)
  331.  *           obj        => Pointer to MUI application
  332.  *   RETURN: ULONG    => Always return 0, error conditions are handled here
  333.  **************************************************************************************************/
  334.  
  335. SAVEDS ASM ULONG PrefsPopupFunc(REG(a0) struct Hook *hook, REG(a1) void *args, REG(a2) APTR obj)
  336.     {
  337.   struct     Window *window;
  338.   struct     FileRequester *req;
  339.     char        *mybuf,FileBuffer[256],buf[512];
  340.     long        myid;
  341.     BOOL    onlydirs = FALSE;
  342.  
  343.     *buf=*FileBuffer='\0';
  344.   set(app,MUIA_Application_Sleep,TRUE);
  345.   get(mainwindow,MUIA_Window  ,&window);
  346.     get(obj,MUIA_String_Contents,&mybuf);
  347.     get(obj,MUIA_UserData,&myid);
  348.   switch(myid)
  349.         {
  350.         case    ID_TITLEFILE:
  351.         case    ID_IPFILE:
  352.         case    ID_ULHELPFILE:  
  353.         case    ID_LOGDIR:            onlydirs = FALSE;
  354.                                                     FAMEStrCopy(FilePart(mybuf),FileBuffer,255);
  355.                           break;
  356.         case    ID_ULTEMPDIR:        onlydirs = TRUE;
  357.                           break;
  358.         }
  359.     if(*FileBuffer)
  360.         {
  361.         FAMEStrMid(mybuf,buf,1,strlen(mybuf)-strlen(FileBuffer));
  362.         }
  363.     else
  364.         {
  365.         FAMEStrCopy(mybuf,buf,255);
  366.         }
  367.   if(req=MUI_AllocAslRequestTags(ASL_FileRequest,TAG_DONE))
  368.         {
  369.     if (MUI_AslRequestTags(req,    ASLFO_Window        ,window,
  370.                                                          ASLFO_PrivateIDCMP  ,TRUE,
  371.                                                         ASLFO_TitleText     ,"Select file...",
  372.                                                                 ASLFR_InitialDrawer    ,buf,
  373.                                                                 ASLFR_InitialFile        ,FileBuffer,
  374.                                                                 ASLFR_DoPatterns        ,TRUE,
  375.                                                                 ASLFR_RejectIcons        ,TRUE,
  376.                                                                 ASLFR_DrawersOnly        ,onlydirs,
  377.                                                                 TAG_DONE))
  378.                     {
  379.                     FAMEFillMem(buf,0,512);
  380.                     FAMEStrCopy(req->fr_Drawer,buf,255);
  381.                     if(onlydirs==FALSE) AddPart(buf,req->fr_File, 512);
  382.                     set(obj,MUIA_String_Contents,buf);
  383.                 }
  384.     MUI_FreeAslRequest(req);
  385.       }
  386.   set(app,MUIA_Application_Sleep,FALSE);
  387.   return(0);
  388.     }
  389.  
  390. /**************************************************************************************************
  391.  * FUNCTION: adv_confunc()
  392.  *  PURPOSE: Hook function for NewList objects - Constructor
  393.  *    INPUT: hook            => Pointer to hook structure
  394.  *           mem_pool    => Global memory pool pointer
  395.  *           fs                => Structure to add to display
  396.  *   RETURN: Either 0 for error or pointer to added list member
  397.  **************************************************************************************************/
  398.  
  399. SAVEDS ASM struct FTPdStats *adv_confunc(REG(a0) struct Hook *hook,REG(a2) APTR mem_pool, REG(a1) struct FTPdStats *fs)
  400.     {
  401.     struct FTPdStats *entry;
  402.  
  403.     entry=AllocPooled(mem_pool,sizeof(struct FTPdStats));
  404.     if(entry)
  405.         {
  406.         CopyMem(fs,entry,sizeof(struct FTPdStats));
  407.         return(entry);
  408.         }
  409.     else return(0);
  410.     }
  411.  
  412. /**************************************************************************************************
  413.  * FUNCTION: adv_desfunc()
  414.  *  PURPOSE: Hook function for NewList objects - Destructor
  415.  *    INPUT: hook            => Pointer to hook structure
  416.  *           mem_pool    => Global memory pool pointer
  417.  *           line            => One member of list to free
  418.  *   RETURN: 0
  419.  **************************************************************************************************/
  420.  
  421. SAVEDS ASM long adv_desfunc(REG(a0) struct Hook *hook,REG(a2) APTR mem_pool,REG(a1) struct FTPdStats *line)
  422.     {
  423.     if(line)
  424.         {
  425.         FreePooled(mem_pool,line,sizeof(struct FTPdStats));
  426.         }
  427.     return(0);
  428.     }
  429.  
  430. /**************************************************************************************************
  431.  * FUNCTION: adv_dspfunc()
  432.  *  PURPOSE: Hook function for NewList objects - Display hook
  433.  *    INPUT: hook        => Pointer to hook structure
  434.  *           array    => Array where to add the entries
  435.  *           line        => One member to add or NULL for initial rendering of titles
  436.  *   RETURN: 0
  437.  **************************************************************************************************/
  438.  
  439. char unum[32],conf[32];
  440.  
  441. SAVEDS ASM long adv_dspfunc(REG(a0) struct Hook *hook,REG(a2) char **array,REG(a1) struct FTPdStats *line)
  442.     {
  443.     if(line)
  444.         {
  445.         *unum=*conf='\0';
  446.  
  447.         if(!line->UserNumber) FAMEStrCopy("N/A",unum,5);
  448.         else
  449.             {
  450.             GetUserName(line->UserNumber,unum);
  451.             }
  452.         if(!line->CurrentConf) FAMEStrCopy("/",conf,5);
  453.         else
  454.             {
  455.             GetConfName(line->CurrentConf,conf);
  456.             }
  457.         *array++=line->TaskAddress;
  458.         *array++=line->ConnectTime;
  459.         *array++=unum;
  460.         *array++=conf;
  461.         *array=line->ActionString;
  462.         }
  463.     else
  464.         {
  465.         *array++="\33bTaskAddress";
  466.         *array++="\33bConnect time";
  467.         *array++="\33bUser";
  468.         *array++="\33bConf";
  469.         *array="\33bCurrent action";
  470.         }
  471.     return(0);
  472.     }
  473.  
  474. /**************************************************************************************************
  475.  * FUNCTION: CreatePopObject()
  476.  *  PURPOSE: Creates a popup (File) object
  477.  *    INPUT: num        => Unique number for this object
  478.  *           key        => Key shortcut to use
  479.  *           help        => Bubble-Help text
  480.  *   RETURN: APTR        => Pointer to object or NULL in case of failure
  481.  **************************************************************************************************/
  482.  
  483. APTR CreatePopObject(long num,char key,char *help)
  484.     {
  485.     return(    PopaslObject,
  486.                         MUIA_Popstring_String, KeyString(0,106,key),
  487.                         MUIA_Popstring_Button, PopButton(MUII_PopFile),
  488.                         MUIA_Popasl_StartHook,&PrefsPopupHook,
  489.                         MUIA_UserData,num,
  490.                         MUIA_ExportID,num,
  491.                         MUIA_HelpNode,help,
  492.                         MUIA_Weight, 200,
  493.                     End);
  494.     }
  495.  
  496. /**************************************************************************************************
  497.  * FUNCTION: CreateKeyButton()
  498.  *  PURPOSE: Creates a button object
  499.  *    INPUT: label    => Labeltext of button
  500.  *           key        => Key shortcut to use
  501.  *           help        => Bubble-Help text
  502.  *   RETURN: APTR        => Pointer to object or NULL in case of failure
  503.  **************************************************************************************************/
  504.  
  505. APTR CreateKeyButton(char *label, char key,char *help)
  506.     {
  507.     return(    TextObject,
  508.                         ButtonFrame,
  509.                         MUIA_Text_Contents,label,
  510.                         MUIA_Text_PreParse,"\33c",
  511.                         MUIA_Text_HiChar,key,
  512.                         MUIA_ControlChar,key,
  513.                         MUIA_InputMode,MUIV_InputMode_RelVerify,
  514.                         MUIA_Background,MUII_ButtonBack,
  515.                         MUIA_HelpNode,help,
  516.                     End);
  517.     }
  518.  
  519. /**************************************************************************************************
  520.  * FUNCTION: CreateKeyCheckMark()
  521.  *  PURPOSE: Creates a checkmark object
  522.  *    INPUT: status    => Initial status of checkmark
  523.  *           key        => Key shortcut to use
  524.  *           help        => Bubble-Help text
  525.  *   RETURN: APTR        => Pointer to object or NULL in case of failure
  526.  **************************************************************************************************/
  527.  
  528. APTR CreateKeyCheckMark(BOOL status, char key, char *help)
  529.     {
  530.     return(    ImageObject,
  531.                         ImageButtonFrame,
  532.                         MUIA_InputMode,MUIV_InputMode_Toggle,
  533.                         MUIA_Image_Spec,MUII_CheckMark,
  534.                         MUIA_Image_FontMatch,TRUE,
  535.                         MUIA_Selected,status,
  536.                         MUIA_Background,MUII_ButtonBack,
  537.                         MUIA_ShowSelState,FALSE,
  538.                         MUIA_ControlChar,key,
  539.                         MUIA_HelpNode, help,
  540.                     End);
  541.     }
  542.  
  543. /**************************************************************************************************
  544.  * FUNCTION: CreateInteger()
  545.  *  PURPOSE: Creates an integer object
  546.  *    INPUT: key            => Key shortcut to use
  547.  *           weight     => Weight Factor for rendering
  548.  *           maxlen     => Maximum of characters allowed
  549.  *           contents => Default value for gadget
  550.  *           help            => Bubble-Help text
  551.  *   RETURN: APTR            => Pointer to object or NULL in case of failure
  552.  **************************************************************************************************/
  553.  
  554.  
  555. APTR CreateInteger(char key,long weight,long maxlen,long contents,char *help)
  556.     {
  557.     return(StringObject,
  558.                         StringFrame,
  559.                         MUIA_ControlChar,key,
  560.                         MUIA_Weight,weight,
  561.                         MUIA_String_Accept,"0123456789",
  562.                         MUIA_String_MaxLen,maxlen,
  563.                         MUIA_String_Integer,contents,
  564.                         MUIA_HelpNode,help,
  565.                 End);
  566.     }
  567.  
  568. /**************************************************************************************************
  569.  * FUNCTION: fail()
  570.  *  PURPOSE: General failure function. Uses EasyRequest for warning infos if app is not loaded yet
  571.  *    INPUT: app            => Application Pointer
  572.  *           *str            => Error string
  573.  *                     withexit    => TRUE = Exit after displaying message. FALSE = do not exit application
  574.  *   RETURN: none
  575.  **************************************************************************************************/
  576.  
  577. VOID fail(APTR thisapp,char *str,BOOL noexit)
  578.     {
  579.   if (*str)
  580.       {
  581.         if(thisapp) MUI_Request(app, mainwindow, 0,"FAME-FTPdCFG Warning:","Okay!","\33c%s", str);
  582.         else
  583.             {
  584.             struct EasyStruct MyES=
  585.                 {
  586.                 sizeof(struct EasyStruct),
  587.                 0,
  588.                 NULL,
  589.          "%s",
  590.          "Okay",
  591.                 };
  592.          EasyRequest(NULL,&MyES,NULL,str);
  593.             }
  594.       }
  595.     if(noexit==FALSE) return;
  596.     if (app)                         MUI_DisposeObject(app);
  597.     if(fib)                            FreeDosObject(DOS_FIB,fib); fib = NULL;
  598.     if(mem_pool)          DeletePool(mem_pool); mem_pool = NULL;
  599.   if (MUIMasterBase)     CloseLibrary(MUIMasterBase); MUIMasterBase=NULL;
  600.     if (UtilityBase)         CloseLibrary(UtilityBase); UtilityBase=NULL;
  601.     if (FAMEBase)             CloseLibrary((struct Library *)FAMEBase);    FAMEBase=NULL;
  602.     if(IntuitionBase)        CloseLibrary((struct Library *)IntuitionBase); IntuitionBase = NULL;
  603.   exit(0);
  604.     }
  605.  
  606. /**************************************************************************************************
  607.  * FUNCTION: ShowAbout()
  608.  *  PURPOSE: Opens the well-known About dialog :)
  609.  *    INPUT: none
  610.  *   RETURN: none
  611.  **************************************************************************************************/
  612.  
  613. STATIC void ShowAbout(void)
  614.     {
  615.     APTR titeltext,titeltxt2,mypic;
  616.     long    status;
  617.  
  618.     SubWindow, aboutwin=WindowObject,
  619.         MUIA_Window_Title            ,    "About FAME-FTPdCFG",
  620.         MUIA_Window_RefWindow    , mainwindow,
  621.         MUIA_Window_NoMenus        ,    TRUE,
  622.         MUIA_Window_SizeGadget, FALSE,
  623.         MUIA_Background           , MUII_BACKGROUND,
  624.         WindowContents, VGroup,TextFrame,
  625.             Child, VSpace(3),
  626.                 Child, titeltext=TextObject,End,
  627.                 Child, HGroup,
  628.                     Child, ColGroup(3),
  629.                         Child, HSpace(0),
  630.                         Child, mypic=BodychunkObject,MUIA_Bodychunk_Body,BODY_inno_Data,MUIA_Bodychunk_Depth,BODY_inno_Depth,MUIA_Bodychunk_Masking,BODY_inno_Masking,MUIA_Bodychunk_Compression,BODY_inno_Compression,MUIA_Bitmap_SourceColors,BODY_inno_Colors,MUIA_Bitmap_Transparent,BODY_inno_Transparent,MUIA_Bitmap_Width,BODY_inno_Width,MUIA_Bitmap_Height,BODY_inno_Height,MUIA_FixHeight,BODY_inno_Height,MUIA_FixWidth,BODY_inno_Width,End,
  631.                         Child, HSpace(0),
  632.                     End,
  633.                 End,
  634.                 Child, titeltxt2=TextObject,End,
  635.             End,
  636.         End;
  637.     if(!aboutwin) fail(app, "Cannot open about window!",TRUE);
  638.     DoMethod(aboutwin,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,MUIM_Application_ReturnID,ID_ABOUTCLOSE);
  639.     DoMethod(titeltext,MUIM_SetAsString,MUIA_Text_Contents,"\33c\33bFAME-FTPdCFG V%s\33n Build %ld (%s)\n(c) 2003,2004 by Sascha 'SieGeL/tRSi' Pfalz of",COMPILE_VERSION,COMPILE_BUILD,COMPILE_DATE);
  640.     DoMethod(titeltxt2,MUIM_SetAsString,MUIA_Text_Contents,"\033cThis Application configures the FAME FTP Server\n\n\033i\033uGreetings must go to:\033n\n\nAndreas 'Bysis' Lorenz for helping with TCP/IP problems\n\n\033i\033uBetatester:\033n\n\ndIGIMAN/tRSi, aRGON/tRSi, eXON, Elvin");
  641.     DoMethod(app, OM_ADDMEMBER, aboutwin);
  642.   set(app,MUIA_Application_Sleep,TRUE);
  643.      set(aboutwin,MUIA_Window_Open,TRUE);
  644.     get(aboutwin,MUIA_Window_Open,&status);
  645.     if(!status) fail(app,"Cannot open about window!",TRUE);
  646.     }
  647.  
  648. /**************************************************************************************************
  649.  * FUNCTION: RemoveAboutWin()
  650.  *  PURPOSE: Closes the About window
  651.  *    INPUT: none
  652.  *   RETURN: none
  653.  **************************************************************************************************/
  654.  
  655. STATIC void RemoveAboutWin(void)
  656.     {
  657.     set(aboutwin,MUIA_Window_Open,FALSE);
  658.     DoMethod(app,OM_REMMEMBER, aboutwin);
  659.     MUI_DisposeObject(aboutwin);aboutwin=NULL;
  660.   set(app,MUIA_Application_Sleep,FALSE);
  661.     }
  662.  
  663. /**************************************************************************************************
  664.  * FUNCTION: DoubleStart()
  665.  *  PURPOSE: Avoids doublestarting of the application
  666.  *    INPUT: none
  667.  *   RETURN: none
  668.  **************************************************************************************************/
  669.  
  670. STATIC void DoubleStart(void)
  671.     {
  672.  
  673.     DoMethod(mainwindow,MUIM_Window_ToFront);
  674.     set(mainwindow,MUIA_Window_Activate,TRUE);
  675.     }
  676.  
  677. /**************************************************************************************************
  678.  * FUNCTION: SavePrefs()
  679.  *  PURPOSE: Saves the preferences
  680.  *    INPUT: none
  681.  *   RETURN: none
  682.  **************************************************************************************************/
  683.  
  684. STATIC void SavePrefs(void)
  685.     {
  686.     BPTR    fp;
  687.     long    rc;
  688.     char    ioerr[80],buffer[256];
  689.     ULONG    x;
  690.     int        p_lo,p_hi;
  691.  
  692.     // Retrieve data from all Gadgets and set preferences accordingly:
  693.  
  694.     FAMEFillMem(fconfig,0,sizeof(struct FTPdConfig));
  695.  
  696.     // Retrieve string gadgets:
  697.  
  698.     get(howto            ,    MUIA_String_Contents,&x);    FAMEStrCopy((char *)x,fconfig->HowToUploadFile,255);
  699.     get(uldir            , MUIA_String_Contents,&x);    FAMEStrCopy((char *)x,fconfig->UploadTempPath,255);
  700.     get(ipfile        , MUIA_String_Contents,&x);    FAMEStrCopy((char *)x,fconfig->IPFile,255);
  701.     get(titlefile    , MUIA_String_Contents,&x);    FAMEStrCopy((char *)x,fconfig->TitleFile,255);
  702.     get(logdir        ,    MUIA_String_Contents,&x);    FAMEStrCopy((char *)x,fconfig->LogFile,255);
  703.  
  704.     // Retrieve integer gadgets:
  705.  
  706.     get(portlo        , MUIA_String_Contents,&x);    p_lo = FAMEAtol((char *)x);
  707.     get(porthi        , MUIA_String_Contents,&x);    p_hi = FAMEAtol((char *)x);
  708.     get(maxusers    , MUIA_String_Contents,&x);    fconfig->MaxUsers = FAMEAtol((char *)x);
  709.  
  710.     // Perform some sanity checking for passive port ranges:
  711.  
  712.     if(p_lo > 0 && p_hi > 0)
  713.         {
  714.         if(p_lo >= p_hi)
  715.             {
  716.             SPrintf(buffer,"Passive port range invalid!\nStart value (%ld) must be lower than end value (%ld)!",p_lo,p_hi);
  717.             fail(app,buffer,FALSE);
  718.             return;
  719.             }
  720.         if(((p_hi - 5) <= 0) || ((p_hi - 5) < p_lo))
  721.             {
  722.       fail(app,"Port range is too small!!\nRange MUST be at least 5 numbers!\nSaving aborted!\n",FALSE);
  723.             return;
  724.             }
  725.         fconfig->PortLo = p_lo;
  726.         fconfig->PortHi = p_hi;
  727.         }
  728.     else        // Both values must be set to have effect, else we use automatic port assignment
  729.       {
  730.     fconfig->PortLo = 0;
  731.         fconfig->PortHi = 0;
  732.         }
  733.  
  734.     // Retrieve checkmarks:
  735.  
  736.     get(debugwin,    MUIA_Selected,&x);    if(x) fconfig->Flags1|=CFG_USEDEBUG;
  737.     get(usedns,        MUIA_Selected,&x);    if(x) fconfig->Flags1|=CFG_USEDNS;
  738.     get(weektop,    MUIA_Selected,&x);    if(x) fconfig->Flags1|=CFG_WEEKTOP;
  739.  
  740.     // Retrieve numeric gadgets:
  741.  
  742.     get(fnamelength, MUIA_Numeric_Value,&x);    fconfig->FileNameLength = x;
  743.     get(fbufsize,      MUIA_Numeric_Value,&x);    fconfig->FileBufferSize = x;
  744.     get(timeout,          MUIA_Numeric_Value,&x);        fconfig->Timeout                 = x*60;    // Have to save in seconds
  745.  
  746.     if(fp = Open(prefspath,MODE_NEWFILE))
  747.         {
  748.         rc = Write(fp,fconfig,sizeof(struct FTPdConfig));
  749.         Close(fp);
  750.         if(rc != sizeof(struct FTPdConfig))
  751.             {
  752.       fail(app,"Saved data seems to be broken or not saved correctly!",FALSE);
  753.             }
  754.         }
  755.     else
  756.         {
  757.         Fault(IoErr(),NULL,ioerr,80);
  758.         SPrintf(buffer,"SavePrefs failed: %s",ioerr);
  759.     fail(app,buffer,FALSE);
  760.         }
  761.     }
  762.  
  763. /**************************************************************************************************
  764.  * FUNCTION: LoadPrefs()
  765.  *  PURPOSE: Loads the preferences. If file not found we use the cleared struct
  766.  *    INPUT: none
  767.  *   RETURN: none
  768.  **************************************************************************************************/
  769.  
  770. STATIC void LoadPrefs(void)
  771.     {
  772.     BPTR    fp;
  773.     char    buffer[256];
  774.  
  775.     if(fp = Open(prefspath,MODE_OLDFILE))
  776.         {
  777.         ExamineFH(fp,fib);
  778.         if(fib->fib_Size != sizeof(struct FTPdConfig))
  779.             {
  780.             SPrintf(buffer,"Your Preferences file is outdated!\nYour prefs file is %ld bytes, but it has to be %ld bytes.\nPlease configure all options and SAVE the preferences\nto save the latest version.",fib->fib_Size,sizeof(struct FTPdConfig));
  781.             fail(NULL,buffer,FALSE);
  782.             }
  783.         Read(fp,fconfig,sizeof(struct FTPdConfig));
  784.         Close(fp);
  785.         }
  786.     if(!fconfig->FileNameLength)     fconfig->FileNameLength = 12;
  787.     if(!fconfig->Timeout)         fconfig->Timeout = 600;                // Defaults to 10 minutes
  788.     }
  789.  
  790. /**************************************************************************************************
  791.  * FUNCTION: UpdateStatDisplay()
  792.  *  PURPOSE: Refreshes the StatsDisplay (TrackMonitor)
  793.  *    INPUT: none
  794.  *   RETURN: none
  795.  **************************************************************************************************/
  796.  
  797. STATIC void UpdateStatDisplay(void)
  798.     {
  799.     struct    FTPdStats    *mydata;
  800.   long    cnt = 0,myentries,i;
  801.     BPTR    fp;
  802.     static    char noconns[]="Currently there are no active FTP connections";
  803.  
  804.     DoMethod(adv_lv, MUIM_List_Clear);
  805.     while(cnt < STATS_FILE_RETRY)
  806.         {
  807.         if(!(fp = Open(statname,MODE_OLDFILE)))        // File is accessed by many instances!
  808.             {
  809.             if(IoErr()==ERROR_OBJECT_NOT_FOUND)            // IoErr() = 205, this is okay and not treated as error
  810.                 {
  811.                 DoMethod(adv_txt,MUIM_SetAsString,MUIA_Text_Contents,"\033c%s",noconns);
  812.                 return;
  813.         }
  814.             cnt++;
  815.             Delay(STATS_RETRY_DELAY);
  816.             continue;
  817.             }
  818.         ExamineFH(fp,fib);
  819.         myentries = fib->fib_Size / sizeof(struct FTPdStats);
  820.         if(!myentries)                                                        // File has 0 entries, okay as it shows no active connections
  821.             {
  822.             Close(fp);
  823.             DoMethod(adv_txt,MUIM_SetAsString,MUIA_Text_Contents,"\033c%s",noconns);
  824.             return;
  825.             }
  826.         if(!(mydata = AllocPooled(mem_pool,sizeof(struct FTPdStats) * (myentries+1))))
  827.             {
  828.             Close(fp);
  829.         fail(NULL,"Cannot allocate memory for statistics??",FALSE);
  830.             return;
  831.             }
  832.     for(i = 0; i < myentries; i++)
  833.             {
  834.       if(!Read(fp,&mydata[i],sizeof(struct FTPdStats)))
  835.                 {
  836.                 Close(fp);
  837.         fail(NULL,"Error reading statsfile",FALSE);
  838.                 return;
  839.                 }
  840.             }
  841.         Close(fp);
  842.         for(i = 0; i < myentries; i++)
  843.             {
  844.             DoMethod(adv_lv,MUIM_List_InsertSingle,&mydata[i],MUIV_List_Insert_Sorted);
  845.             }
  846.         FreePooled(mem_pool,mydata,sizeof(struct FTPdStats) * (myentries+1));
  847.         DoMethod(adv_txt,MUIM_SetAsString,MUIA_Text_Contents,"\033cCurrently there are %ld active connection(s)",myentries);
  848.         return;
  849.         }
  850.     }
  851.  
  852. /**************************************************************************************************
  853.  * FUNCTION: GetUserName()
  854.  *  PURPOSE: Retrieves the Username and copy it to the supplied buffer
  855.  *    INPUT: userid => Userid to retrieve
  856.  *           buffer => Name will be copied here (32 bytes!)
  857.  *   RETURN: none
  858.  **************************************************************************************************/
  859.  
  860. void GetUserName(long userid, char *buffer)
  861.     {
  862.   struct    FAMEConfigRequest *fcr;
  863.   struct    FAMEUserKeys            *myuserdata;
  864.     long        myresult=0;
  865.  
  866.   fcr = AllocPooled(mem_pool,sizeof(struct FAMEConfigRequest));
  867.     if(!fcr)
  868.         {
  869.     fail(NULL,"Unable to allocate fcr struct!",FALSE);
  870.          return;
  871.         }
  872.     FAMERequestReset(fcr);
  873.     fcr->fcr_CfgUserTask         = FindTask(NULL);
  874.     fcr->fcr_CfgUserName         = "FAME-FTPdCFG";
  875.     fcr->fcr_CfgUserDesc         = "FAME-FTPdCFG Editor";
  876.   fcr->fcr_ConfigType          = FCDD_UserKeys;                    // We want the FAME user.data
  877.     fcr->fcr_ConfigMode          = FAMECFG_MODE_READ;             // Nothing will be changed here!
  878.   fcr->fcr_ConfigNum             = userid;                                    // Search for the Username in user.data
  879.     myuserdata = FAMEObtainConfig(fcr,&myresult);
  880.     if(myuserdata)
  881.         {
  882.     FAMEStrCopy(myuserdata->UserName,buffer,31);
  883.     }
  884.     else
  885.         {
  886.         FAMEStrCopy("N/A",buffer,31);
  887.         }
  888.     FAMEReleaseConfig( myuserdata, FAMECFG_MODE_READ, FindTask( NULL ));
  889.     FreePooled(mem_pool,fcr,sizeof(struct FAMEConfigRequest));
  890.     }
  891.  
  892. /**************************************************************************************************
  893.  * FUNCTION: GetConfName()
  894.  *  PURPOSE: Retrieves the conference name and copy it to the supplied buffer
  895.  *    INPUT: confid => Conference number to retrieve
  896.  *           buffer => Name will be copied here (32 bytes!)
  897.  *   RETURN: none
  898.  **************************************************************************************************/
  899.  
  900. void GetConfName(long confid, char *buffer)
  901.     {
  902.   struct    FAMEConfigRequest *fcr;
  903.   struct    FAMEConf                    *myconf;
  904.     long        myresult=0;
  905.  
  906.   fcr = AllocPooled(mem_pool,sizeof(struct FAMEConfigRequest));
  907.     if(!fcr)
  908.         {
  909.     fail(NULL,"Unable to allocate fcr struct!",FALSE);
  910.          return;
  911.         }
  912.     FAMERequestReset(fcr);
  913.     fcr->fcr_CfgUserTask         = FindTask(NULL);
  914.     fcr->fcr_CfgUserName         = "FAME-FTPdCFG";
  915.     fcr->fcr_CfgUserDesc         = "FAME-FTPdCFG Editor";
  916.   fcr->fcr_ConfigType          = FCDD_Conf;                            // We want the FAME confname
  917.     fcr->fcr_ConfigMode          = FAMECFG_MODE_READ;             // Nothing will be changed here!
  918.   fcr->fcr_ConfigNum             = confid;
  919.     myconf = FAMEObtainConfig(fcr,&myresult);
  920.     if(myconf)
  921.         {
  922.     FAMEStrCopy(myconf->ConfName,buffer,31);
  923.     }
  924.     else
  925.         {
  926.         FAMEStrCopy("N/A",buffer,31);
  927.         }
  928.     FAMEReleaseConfig( myconf, FAMECFG_MODE_READ, FindTask( NULL ));
  929.     FreePooled(mem_pool,fcr,sizeof(struct FAMEConfigRequest));
  930.     }
  931.